package com.shenma2009.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.shenma2009.domain.ResultResponse;
import com.shenma2009.pojo.TbUser;
import com.shenma2009.service.TbUserService;
import com.shenma2009.mapper.TbUserMapper;
import com.shenma2009.utils.TokenUtils;
import com.shenma2009.vo.*;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.security.crypto.bcrypt.BCrypt;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.stream.Collectors;

/**
* @author 33509
* @description 针对表【tb_user(用户表)】的数据库操作Service实现
* @createDate 2023-04-19 15:48:14
*/
@Service
public class TbUserServiceImpl extends ServiceImpl<TbUserMapper, TbUser>
    implements TbUserService{

    @Autowired
    RedisTemplate<String, Object> redisTemplate;

    @Value("${site.token.key}")
    String tokenKey;

    @Override
    public ResultResponse add(TbUserVo tbUserVo) {
        //-- 判断是否有同名用户
        QueryWrapper<TbUser> wrapper = new QueryWrapper<>();
        wrapper.lambda().eq(TbUser::getUserName, tbUserVo.getUserName()).last("limit 1");

        TbUser one = this.getOne(wrapper);
        if(one != null) {
            return ResultResponse.FAILED(500, "用户已存在");
        }

        //-- 生成密码
        TbUser tbUser = new TbUser();
        BeanUtils.copyProperties(tbUserVo, tbUser);

        String pass = BCrypt.hashpw(tbUser.getUserPass(), BCrypt.gensalt());
        tbUser.setUserPass(pass);

        //-- 存入数据库
        this.save(tbUser);

        return ResultResponse.SUCCESS();
    }

    @Override
    public ResultResponse del(IdVo idVo) {
        //--1 判断有没有
        TbUser tbUser = this.getById(idVo.getId());
        if(tbUser == null) {
            return ResultResponse.FAILED(404, "用户不存在");
        }

        //--2 删除
        this.removeById(idVo.getId());

        return ResultResponse.SUCCESS();
    }

    @Override
    public ResultResponse set(TbUserVo tbUserVo) {
        //--1 判断是否存在
        TbUser tbUser = this.getById(tbUserVo.getUserId());
        if(tbUser == null) {
            return ResultResponse.FAILED(404, "用户不存在");
        }

        //--2 修改
        TbUser user = new TbUser();
        BeanUtils.copyProperties(tbUserVo, user);
        // 密码不修改
        user.setUserPass(null);

        this.updateById(user);

        return ResultResponse.SUCCESS();
    }

    @Override
    public ResultResponse get(IdVo idVo) {
        TbUser tbUser = this.getById(idVo.getId());
        if(tbUser == null) {
            return ResultResponse.FAILED(404, "用户不存在");
        }

        // 脱密
        tbUser.setUserPass(null);

        return ResultResponse.SUCCESS(tbUser);
    }

    @Override
    public ResultResponse listByPage(PageVo pageVo) {

        Page<TbUser> page = new Page<>(pageVo.getPageNum(), pageVo.getPageSize());

        Page<TbUser> tbUserPage = this.page(page);

        List<TbUserVo> collect = tbUserPage.getRecords().stream().map(item -> {
            TbUserVo tbUserVo = new TbUserVo();
            BeanUtils.copyProperties(item, tbUserVo);
            tbUserVo.setUserPass(null);
            return tbUserVo;
        }).collect(Collectors.toList());

        Page<TbUserVo> userVoPage = new Page<>();
        BeanUtils.copyProperties(tbUserPage, userVoPage);
        userVoPage.setRecords(collect);

        return ResultResponse.SUCCESS(userVoPage);
    }

    @Override
    public ResultResponse resetUserPass(UserPassVo userPassVo) {
        //--1 判断是否存在
        TbUser tbUser = this.getById(userPassVo.getUserId());
        if(tbUser == null) {
            return ResultResponse.FAILED(404, "用户不存在");
        }

        //--2 判断密码是否正确
        boolean checkpw = BCrypt.checkpw(userPassVo.getOldPass(), tbUser.getUserPass());
        if(!checkpw) {
            return ResultResponse.FAILED(500, "密码不正确");
        }

        //--3 修改密码
        String hashpw = BCrypt.hashpw(userPassVo.getNewPass(), BCrypt.gensalt());
        tbUser.setUserPass(hashpw);

        tbUser.setUpdateTime(null);
        this.updateById(tbUser);

        return ResultResponse.SUCCESS();
    }

    @Override
    public ResultResponse login(LoginInfoVo loginInfoVo) {
        //--1 判断用户是否存在
        QueryWrapper<TbUser> wrapper = new QueryWrapper<>();
        wrapper.lambda().eq(TbUser::getUserName, loginInfoVo.getUserName()).last("limit 1");

        TbUser one = this.getOne(wrapper);
        if(one == null) {
            return ResultResponse.FAILED(404, "用户不存在");
        }

        //--2 判断密码是否真确
        boolean checkpw = BCrypt.checkpw(loginInfoVo.getUserPass(), one.getUserPass());
        if(!checkpw) {
            return ResultResponse.FAILED(403, "密码不正确");

        }

        //--3 返回token
        // accessToken： 用来操作
        // freshToken： 用来换取新的accessToken
        TokenUtils tokenUtils = TokenUtils.token();
        String token = tokenUtils.setKey(tokenKey)
                .setExpire(60 * 10)
                .setClaim("userId", "" + one.getUserId())
                .setClaim("userName", one.getUserName())
                .makeToken();

        //
        TbUserVo tbUserVo = new TbUserVo();
        BeanUtils.copyProperties(one, tbUserVo);

        tbUserVo.setUserPass(null);
        tbUserVo.setAccessToken(token);

        //--4 存储token到redis中
        redisTemplate.opsForValue().set(token, token);

        return ResultResponse.SUCCESS(tbUserVo);
    }
}




